package com.lily.aidouzixun;

import android.app.Application;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.support.v4.util.ArrayMap;
import android.util.SparseArray;

import com.lily.aidouzixun.datacenter.DataReuireOperate;
import com.lily.aidouzixun.message.MessageDispatcher;
import com.lily.aidouzixun.message.MessageType;
import com.lily.aidouzixun.threadpool.GrandCentralPool;
import com.lily.aidouzixun.util.L;
import com.lily.aidouzixun.util.MyConstant;
import com.lily.aidouzixun.util.MyCrashHandler;

/**
 * 程序主入口
 */
public class MyApplication extends Application{
    private static final String TAG = "MyApplication";

    private static Context context;
    private static boolean inited = false;  //是否初始化了
    private static MyHandler appHandler;
    private static ArrayMap<String, Handler> callHandlerMap;   //请求端Handler对象的Map集合
    private static ArrayMap<String, EventsAsyncTask> eventsAsyncTaskMap;   //异步任务对象的Map集合

    public void onCreate() {
        L.i(TAG, "onCreate begin!");

        super.onCreate();

        globalInit();
        L.i(TAG, "onCreate end!");
    }

    /**
     * 初始化方法
     */
    public void globalInit() {
        L.i(TAG, "globalInit begin!");
        if(inited) {
            return;
        }
        callHandlerMap = new ArrayMap<String, Handler>();
        eventsAsyncTaskMap = new ArrayMap<String, EventsAsyncTask>();
        initContext();
        initThreadPool();
        initHandler();
        initSendCrashLog();
        inited = true;

        L.i(TAG, "globalInit end!");
    }

    /**
     * 初始化发送崩溃日记
     */
    private void initSendCrashLog() {
        try {   //初始化异常捕获对象
            MyCrashHandler crashHandler = MyCrashHandler.getInstance();
            crashHandler.init(context);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //发送crashlog
        ArrayMap<String, Object> crashLogMap = new ArrayMap<String, Object>();
        crashLogMap.put(MyConstant.RequireParams.DATA_TYPE, MyConstant.DataType.SEND_CRASH_LOG);
        crashLogMap.put(MyConstant.RequireParams.MAP_KEY, "@" + MyConstant.DataType.LONGDISTANCE_COMMENT);
        MessageDispatcher.sendMessage(MyApplication.getHandler(), MessageType.REQUIRE_DATA, crashLogMap);
    }

    /**
     * 初始化appContext
     */
    private void initContext() {
        if(context == null) {
            context = getApplicationContext();
        }
    }

    /**
     * 初始化线程池方法
     */
    public void initThreadPool() {
        GrandCentralPool.initAll(4);
    }

    /**
     * 初始化Handler对象
     */
    private static void initHandler() {
        appHandler = new MyHandler();
    }

    /**
     * @return handler对象
     */
    public static Handler getHandler() {
        if(appHandler == null) {
            initHandler();
        }
        return appHandler;
    }

    /**
     *  处理数据请求
     * @param obj 请求参数-ArrayMap<String, Object>
     */
    private static void processRequireData(Object obj) {
        L.i(TAG, "processRequireData!");

        if(obj == null) {
            return;
        }

        ArrayMap<String, Object> params = (ArrayMap<String, Object>)obj;
        Handler callbackHandler = (Handler)params.get(MyConstant.RequireParams.CALL_BACK_HANDLER);
        int dataType = (Integer) params.get(MyConstant.RequireParams.DATA_TYPE);
        MessageDispatcher.sendMessage(callbackHandler, MessageType.SHOW_DIALOG, dataType, null);
        String mapKey = (String)params.get(MyConstant.RequireParams.MAP_KEY);
        /**
         * 1.创建一个异步任务
         * 2.把回调handler和执行该操作的任务加到map中，取得结果以后，通过key来得到或移除
         */
        EventsAsyncTask eventAsyncTask = new EventsAsyncTask(new DataReuireOperate(context, appHandler, params));
        eventsAsyncTaskMap.put(mapKey, eventAsyncTask);
        callHandlerMap.put(mapKey, callbackHandler);
        //第二个eventAsyncTask为DataRequire中搞定requireOperate方法中的参数
        GrandCentralPool.executeDataAsyncTask(eventAsyncTask, eventAsyncTask);
    }

    /**
     * 处理数据请求结果
     * @param dataType 数据类型
     * @param obj    请求结果对象 SparseArray<Object> obj[0]-key,obj[1]-resultObj.至少要有obj[0],可以没有obj[1]
     */
    private static void processRequireDataFinished(int dataType, Object obj) {
        L.i(TAG, "processRequireDataFinished!");
        if(obj == null) {
            return;
        }
        SparseArray<Object> result = (SparseArray<Object>) obj;
        if(result.size() > 0) {
            String key = (String) result.get(0);
            EventsAsyncTask task = eventsAsyncTaskMap.get(key);
            if(task.isCancelled() == false) {
                Handler callbackHandler = callHandlerMap.get(key);
                if(callbackHandler != null) {
                    Object requireResultData = result.get(1);
                    //发送消息给请求端，通知处理请求数据结果，结果为obj
                    MessageDispatcher.sendMessage(callbackHandler, MessageType.REQUIRE_DATA_FINISHED, dataType, requireResultData);
                    //关闭请求等待框
                    MessageDispatcher.sendMessage(callbackHandler, MessageType.CLOSE_DIALOG, dataType, null);
                }
            }
        }

    }

    /**
     * 取消任务
     * @param inputKey
     */
    private static void processRequireCancel(String inputKey) {
        EventsAsyncTask workAsyncTask = eventsAsyncTaskMap
                .remove(inputKey);// soldier
        try {
            if (workAsyncTask != null && !workAsyncTask.isCancelled()) {
                    L.d(TAG, "----RequireCancel, will interrupt key="
                            + inputKey + ", task=" + workAsyncTask);
                workAsyncTask.cancel(true);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        callHandlerMap.remove(inputKey);
    }


    /**
     * Applicaiton 中的 Handler对象
     */
    private static class MyHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            try {
                switch (msg.what) {

                    case MessageType.REQUIRE_DATA:  //请求数据  msg.obj-ArrayMap<String, Object>
                        processRequireData(msg.obj);
                        break;

                    case MessageType.REQUIRE_DATA_FINISHED: //请求数据完成 arg1-datyTpye;arg2-arg2;obj-请求结果对象
                        processRequireDataFinished(msg.arg1, msg.obj);
                        break;

                    case MessageType.REQUIRE_CANCEL: //取消请求数据任务msg.obj-要被取消的任务key
                        processRequireCancel((String) msg.obj);
                        break;

                }
            } catch (Exception e) {
                L.e(TAG, "MyApplication-initHandler-Exception!");
            }
        }
    }

    /**
     * 异步任务类，所有需要启动线程的操作，都走该类
     */
    private static class EventsAsyncTask extends AsyncTask<Object, Object,Object> {
        DataReuireOperate dataReuireOperate;

        public EventsAsyncTask(DataReuireOperate dataReuireOperate) {
            this.dataReuireOperate = dataReuireOperate;
        }

        @Override
        protected Object doInBackground(Object... params) {
            if(this.dataReuireOperate != null) {
                this.dataReuireOperate.requireOprate((AsyncTask<Object, Object,Object>) params[0]);
            }
            return null;
        }
    }


}
